package com.gitee.qdbp.jdbc.result;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
import com.gitee.qdbp.tools.utils.NamingTools;

/**
 * KEY由驼峰命名法转换的ColumnMapRowMapper<br>
 * 如果存在同名字段, 以先出现的为准, 忽略后出现的
 *
 * @author zhaohuihua
 * @version 20201109
 */
public class CamelNamingMapRowMapper implements RowMapper<Map<String, Object>> {

    @Override
    public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Map<String, Object> mapOfColumnValues = createColumnMap(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
            if (mapOfColumnValues.containsKey(key)) {
                continue;
            }
            Object object = getColumnValue(rs, i);
            mapOfColumnValues.put(key, object);
        }
        return mapOfColumnValues;
    }

    /**
     * Create a Map instance to be used as column map.<br>
     * By default, a linked case-insensitive Map will be created.
     * 
     * @param columnCount the column count, to be used as initial capacity for the Map
     * @return the new Map instance
     * @see org.springframework.util.LinkedCaseInsensitiveMap
     */
    protected Map<String, Object> createColumnMap(int columnCount) {
        return new LinkedCaseInsensitiveMap<Object>(columnCount);
    }

    protected String getColumnKey(String columnName) {
        // 表别名与列别名的分隔符, 见DbTools.parseAllFieldColumns();
        String tableAliasSeparator = "__";
        int tableAliasIndex = columnName.indexOf(tableAliasSeparator);
        if (tableAliasIndex >= 0) {
            columnName = columnName.substring(tableAliasIndex + tableAliasSeparator.length());
        }
        return NamingTools.toCamelString(columnName);
    }

    protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
        return JdbcUtils.getResultSetValue(rs, index);
    }

}
